package com.ww.dynamic.spel;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 变量
 * 变量可以在表达式中使用语法“#变量名”引用，变量设置使用EvaluationContext#setVariable(var, value)方法，var为变量名称，value为变量对应的值
 */
public class ObjectExprSample {

    public static void main(String[] args) {
        User user = new User("tom");
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(user);

        // 为newUserName变量设置新值
        context.setVariable("newUserName", "jony");

        // 取变量值，并赋值
        parser.parseExpression("userName=#newUserName").getValue(context);
        System.out.println(user.getUserName());

        // this变量值使用
        List<Integer> credits = new ArrayList<>();
        credits.addAll(Arrays.asList(150, 100, 90, 50, 110, 130, 70));
        context.setVariable("credits", credits);
        List<Integer> creditsGreater100 = (List<Integer>) parser.parseExpression("#credits.?[#this>100]").getValue(context);
    }

    @ToString
    @Data
    static class User {

        private String userName;

        private Date lastVisit;

        private Integer credits;

        private PropertyExprSample.PlaceOfBirth placeOfBirth;

        public User() {}

        public User(String userName) {
            this.userName = userName;
        }

		public String getUserName() {
			return userName;
		}

		public void setUserName(String userName) {
			this.userName = userName;
		}

		public Date getLastVisit() {
			return lastVisit;
		}

		public void setLastVisit(Date lastVisit) {
			this.lastVisit = lastVisit;
		}

		public Integer getCredits() {
			return credits;
		}

		public void setCredits(Integer credits) {
			this.credits = credits;
		}

		public PropertyExprSample.PlaceOfBirth getPlaceOfBirth() {
			return placeOfBirth;
		}

		public void setPlaceOfBirth(PropertyExprSample.PlaceOfBirth placeOfBirth) {
			this.placeOfBirth = placeOfBirth;
		}
    }

    @ToString
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class PlaceOfBirth {

        private String province;

        private String city;
    }
}
